<?php

/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/2/26 0026
 * Time: 22:21
 */
class Worker
{

    protected $socket;

    public $connect;

    public $message;

    public $addr;

    public $reusePort;

    public function __construct($socket_address)
    {
        $this->addr = $socket_address;
    }

    public function fork()
    {

        for ($i = 0; $i < 2; $i++) {
            $pid = pcntl_fork();
            if ($pid < 0) {
                exit('创建失败');
            } elseif ($pid > 0) {
                //父进程空间 返回子进程ID

            } elseif ($pid == 0) { // 返回0子进程空间
//                sleep(20);
                $this->accept();
                exit();
            }
        }

        $status = 0;
        for ($i = 0; $i < 2; $i++) {
            $pid = pcntl_wait($status); //回收子进程  结束的子进程信息，阻塞状态
        }
        echo "子进程ID=" . $pid . PHP_EOL;
    }

    public function accept()
    {
        $opts = array(
            'socket' => array(
                'bindlog' => 10240,//成功建立连接的等待个数
            ),
        );

        $context = stream_context_create($opts);
        //开启多端口监听并且实现负载均衡
        stream_context_set_option($context, 'socket', 'so_reuseport', 1);
        $this->socket = stream_socket_server($this->addr, $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $context);

//        while (1) {
//
//            if (pcntl_fork() == 0) {
//
//                $client = stream_socket_accept($this->socket);
//                if ($client && is_callable($this->connect)) {
//                    call_user_func_array($this->connect, array($client, '触发连接'));
//                }
//                $clientData = fread($client, 65535);
//                if (!empty($clientData) && is_callable($this->message)) {
//                    call_user_func_array($this->message, array($client, '触发消息事件'));
//                }
//                fclose($client);
//            }
//        }
        var_dump(posix_getgid());
        //第一个需要监听的时间（服务端socket的事件）一旦监听到事件会触发
        swoole_event_add($this->socket, function ($fd) {
            $clientSocket = stream_socket_accept($fd);
            //出发连接事件回调
            if ($clientSocket && is_callable($this->connect)) {
                call_user_func_array($this->connect, array($fd, '触发连接'));
            }
            //监听客户端可读
            swoole_event_add($clientSocket, function ($fd) {
                $clientData = fread($fd, 65535);
                if (!empty($clientData) && is_callable($this->message)) {
                    call_user_func_array($this->message, array($fd, '触发消息事件'));
                }
                fclose($fd);
            });

        });
        echo '非柱塞';
    }

    public function start()
    {
        $this->fork();

    }

}

$worker = new Worker('tcp://0.0.0.0:9501');

$worker->reusePort = true;

$worker->connect = function ($client, $args) {
    var_dump($client, $args);
};
$worker->message = function ($client, $args) {
//    var_dump($client, $args);
    $content = "我是peter";
    $http_resonse = "HTTP/1.1 200 OK\r\n";
    $http_resonse .= "Content-Type: text/html;charset=UTF-8\r\n";
    $http_resonse .= "Connection: keep-alive\r\n"; //连接保持
    $http_resonse .= "Server: php socket server\r\n";
    $http_resonse .= "Content-length: " . strlen($content) . "\r\n\r\n";
    $http_resonse .= $content;
    fwrite($client, $http_resonse);
};
$worker->start();